import os
import time
from PyQt5.QtWidgets import (QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, 
                             QComboBox, QTextEdit, QLabel, QWidget, QFileDialog, 
                             QMessageBox, QDoubleSpinBox, QProgressBar)
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtGui import QTextCursor
import serial.tools.list_ports
from core.serial_thread import SerialThread
from core.file_sender import FileSender

class SerialMonitor(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("GP3700卫星发射终端")
        self.setGeometry(100, 100, 800, 600)
        self.init_ui()
        self.init_connections()
        self.refresh_ports()
        self.serial_thread = None
    
    def init_ui(self):
        from .widgets import PortControlWidget, FileControlWidget, MessageInputWidget
        
        # 创建控件
        self.port_control = PortControlWidget()
        self.file_control = FileControlWidget()
        self.message_input = MessageInputWidget()  # 新增的消息输入控件
        
        # 日志显示
        self.log_display = QTextEdit()
        self.log_display.setReadOnly(True)
        self.clear_btn = QPushButton("清空日志")
        
        # 进度条
        self.progress_bar = QProgressBar()
        
        # 布局设置
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.port_control)
        main_layout.addWidget(self.file_control)
        main_layout.addWidget(self.message_input)  # 添加消息输入控件
        main_layout.addWidget(self.progress_bar)
        main_layout.addWidget(self.log_display)
        main_layout.addWidget(self.clear_btn)
        
        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)
    
    def init_connections(self):
        self.port_control.connect_btn.clicked.connect(self.toggle_connection)
        self.port_control.refresh_btn.clicked.connect(self.refresh_ports)
        self.file_control.file_btn.clicked.connect(self.select_file)
        self.file_control.send_btn.clicked.connect(self.send_file)
        self.clear_btn.clicked.connect(self.clear_log)
        self.message_input.send_btn.clicked.connect(self.send_message)  # 添加消息发送连接
        self.message_input.message_input.returnPressed.connect(self.send_message)  # 回车发送
    
    def refresh_ports(self):
        self.port_control.port_combo.clear()
        ports = serial.tools.list_ports.comports()
        for port in ports:
            self.port_control.port_combo.addItem(port.device)
    
    def toggle_connection(self):
        if self.serial_thread and self.serial_thread.isRunning():
            self.serial_thread.stop()
            self.serial_thread.wait()
            self.port_control.connect_btn.setText("连接")
            self.log_message("串口已断开")
        else:
            port = self.port_control.port_combo.currentText()
            baudrate = int(self.port_control.baud_combo.currentText())
            try:
                self.serial_thread = SerialThread(port, baudrate)
                self.serial_thread.data_received.connect(self.append_received_data)
                self.serial_thread.send_progress.connect(self.progress_bar.setValue)
                self.serial_thread.start()
                self.port_control.connect_btn.setText("断开")
                self.log_message(f"已连接到 {port} ({baudrate} bps)")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"连接失败: {str(e)}")
    
    def select_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "选择文件")
        if file_path:
            self.file_path = file_path
            file_name = os.path.basename(file_path)
            self.file_control.file_btn.setText(file_name)
            self.log_message(f"已选择文件: {file_name}")
    
    def send_file(self):
        if not hasattr(self, 'file_path'):
            QMessageBox.warning(self, "警告", "请先选择文件")
            return
        
        if not self.serial_thread or not self.serial_thread.isRunning():
            QMessageBox.warning(self, "警告", "请先连接串口")
            return
        
        try:
            with open(self.file_path, 'rb') as f:
                data = f.read()
            
            file_size = len(data)
            self.serial_thread.byte_interval = self.file_control.interval_spin.value() / 1000.0
            self.log_message(f"开始发送 {os.path.basename(self.file_path)} ({file_size} 字节)")
            self.log_message(f"字节间隔: {self.serial_thread.byte_interval*1000}ms")
            
            self.progress_bar.setValue(0)
            
            self.send_thread = QThread()
            self.sender = FileSender(data, self.serial_thread)
            self.sender.moveToThread(self.send_thread)
            self.send_thread.started.connect(self.sender.run)
            self.sender.progress.connect(self.progress_bar.setValue)
            self.sender.finished.connect(lambda: self.log_message("文件发送完成!"))
            self.sender.finished.connect(self.send_thread.quit)
            self.sender.finished.connect(self.sender.deleteLater)
            self.send_thread.finished.connect(self.send_thread.deleteLater)
            self.send_thread.start()
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"发送失败: {str(e)}")
    
    def append_received_data(self, data):
        cursor = self.log_display.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(data)
        self.log_display.setTextCursor(cursor)
        self.log_display.ensureCursorVisible()
    
    def log_message(self, message):
        # 移除message中已有的换行符（避免重复换行）
        cleaned_message = message.rstrip('\n').rstrip('\r')
        self.log_display.append(f"[{time.strftime('%H:%M:%S')}] {cleaned_message}\n")
    
    def clear_log(self):
        self.log_display.clear()
    
    def closeEvent(self, event):
        if hasattr(self, 'send_thread') and self.send_thread.isRunning():
            self.send_thread.quit()
            self.send_thread.wait()
        if self.serial_thread and self.serial_thread.isRunning():
            self.serial_thread.stop()
            self.serial_thread.wait()
        event.accept()

    def send_message(self):
        if not self.serial_thread or not self.serial_thread.isRunning():
            QMessageBox.warning(self, "警告", "请先连接串口")
            return
        
        message = self.message_input.message_input.text()
        if not message:
            return
        
        try:
            # 发送消息
            self.serial_thread.send_data(message,add_newline=True)
            # self.log_message(f"发送: {message}")
            # self.message_input.message_input.clear()
        except Exception as e:
            QMessageBox.critical(self, "错误", f"发送失败: {str(e)}")    